package org.codehaus.activemq.transport.reliable;

public class SMLCGRandom
{
  private static final long MULTIPLIER_1 = 40014L;
  private static final long MOD_1 = 2147483563L;
  private static final long MULTIPLIER_2 = 40692L;
  private static final long MOD_2 = 2147483399L;
  private static final int SHUFFLE_LEN = 32;
  private static final int WARMUP_LENGTH = 19;
  private int generated_1;
  private int generated_2;
  private int state;
  private int[] shuffle;

  public SMLCGRandom()
  {
    this(System.currentTimeMillis());
  }

  public SMLCGRandom(long seed)
  {
    this.shuffle = new int[32];
    setSeed(seed);
  }

  public void setSeed(long seed)
    throws IllegalArgumentException
  {
    this.generated_1 = (this.generated_2 = (int)(seed & 0xFFFFFFFF));
    for (int i = 0; i < 19; i++) {
      this.generated_1 = (int)(this.generated_1 * 40014L % 2147483563L);
    }
    for (int i = 0; i < 32; i++) {
      this.generated_1 = (int)(this.generated_1 * 40014L % 2147483563L);
      this.shuffle[(31 - i)] = this.generated_1;
    }
    this.state = this.shuffle[0];
  }

  public short nextShort()
  {
    return (short)((short)nextByte() << 8 | (short)(nextByte() & 0xFF));
  }

  public int nextInt()
  {
    return nextShort() << 16 | nextShort() & 0xFFFF;
  }

  public long nextLong()
  {
    return nextInt() << 32 | nextInt() & 0xFFFFFFFF;
  }

  public float nextFloat()
  {
    return (float)((nextInt() & 0x7FFFFFFF) / 2147483647.0D);
  }

  public double nextDouble()
  {
    return (nextLong() & 0xFFFFFFFF) / 9.223372036854776E+018D;
  }

  public byte nextByte()
  {
    int i = 0;
    this.generated_1 = (int)(this.generated_1 * 40014L % 2147483563L);
    this.generated_2 = (int)(this.generated_2 * 40692L % 2147483399L);
    i = this.state / 67108862;
    i = Math.abs(i);
    this.state = (int)((this.shuffle[i] + this.generated_2) % 2147483563L);
    this.shuffle[i] = this.generated_1;
    return (byte)(this.state / 8388608);
  }
}